import pandas as pd
import plotly.express as px
from dash import Dash, dcc, html, Input, Output
# Load the datasets
confirmed_path = 'time_series_covid19_confirmed_US.csv'
deaths_path = 'time_series_covid19_deaths_US.csv'
# Read the datasets
confirmed_df = pd.read_csv(confirmed_path)
deaths_df = pd.read_csv(deaths_path)
# Remove non-date columns for cleaner processing
confirmed_statewise = confirmed_df.drop(columns=['UID', 'iso2', 'iso3', 'code3', 'FIPS', 'Admin2', 'Country_Region', 'Lat', 'Long_', 'Combined_Key']).groupby('Province_State').sum().transpose()
deaths_statewise = deaths_df.drop(columns=['UID', 'iso2', 'iso3', 'code3', 'FIPS', 'Admin2', 'Country_Region', 'Lat', 'Long_', 'Combined_Key', 'Population']).groupby('Province_State').sum().transpose()
# Convert index to datetime
confirmed_statewise.index = pd.to_datetime(confirmed_statewise.index, format='%m/%d/%y')
deaths_statewise.index = pd.to_datetime(deaths_statewise.index, format='%m/%d/%y')
# Create a Dash application
app = Dash(__name__)
# Layout of the application
app.layout = html.Div([
dcc.Dropdown(
id='year-dropdown',
options=[{'label': i, 'value': i} for i in range(confirmed_statewise.index.year.min(), confirmed_statewise.index.year.max() + 1)],
value=2023 # Default value
),
dcc.Dropdown(
id='month-dropdown',
options=[{'label': i, 'value': i} for i in range(1, 13)],
value=2 # Default value
),
dcc.Graph(id='cfr-plot')
])
# Callback to update the graph based on dropdown selections
@app.callback(
Output('cfr-plot', 'figure'),
[Input('year-dropdown', 'value'),
Input('month-dropdown', 'value')]
)
def update_figure(selected_year, selected_month):
# Filter data based on selected year and month
mask = (confirmed_statewise.index.year == selected_year) & (confirmed_statewise.index.month == selected_month)
confirmed_selected = confirmed_statewise[mask]
deaths_selected = deaths_statewise[mask]
# Calculate CFR
cfr_selected = (deaths_selected / confirmed_selected) * 100
# Calculate the average CFR for the month for each state
average_cfr_selected = cfr_selected.mean()
average_cfr_selected_sorted = average_cfr_selected.sort_index()
# Convert to DataFrame for Plotly
cfr_df = average_cfr_selected_sorted.reset_index()
cfr_df.columns = ['State', 'Average CFR']
# Create an interactive bar chart using Plotly
fig = px.bar(cfr_df, x='State', y='Average CFR',
title=f'Average COVID-19 Case Fatality Rate (CFR) by State for {selected_month}/{selected_year}',
labels={'Average CFR': 'Average CFR (%)', 'State': 'State'},
hover_data={'State': True, 'Average CFR': ':.2f'})
return fig
# Run the app
if __name__ == '__main__':
app.run_server(debug=True)
import pandas as pd
import matplotlib.pyplot as plt
import calendar
from math import pi
from ipywidgets import interact, Dropdown
Loading the COVID-19 datasets, one for confirmed cases and the other for deaths in the United States.
# Load datasets
confirmed_cases_path = 'time_series_covid19_confirmed_US.csv'
deaths_path = 'time_series_covid19_deaths_US.csv'
confirmed_cases = pd.read_csv(confirmed_cases_path)
deaths = pd.read_csv(deaths_path)
Aggregating the data to find the total number of confirmed cases and deaths daily across the US. The series is then converted into a DataFrame, and the index, which represents dates, is converted into a datetime format for better handling in subsequent analyses.
# Sum up all columns except the initial meta data columns to get total cases and deaths per day across the US
total_cases_daily = confirmed_cases.iloc[:, 11:].sum(axis=0)
total_deaths_daily = deaths.iloc[:, 12:].sum(axis=0)
# Convert the series to a DataFrame for easier manipulation and plotting
total_cases_daily = pd.DataFrame(total_cases_daily, columns=['Total_Cases'])
total_deaths_daily = pd.DataFrame(total_deaths_daily, columns=['Total_Deaths'])
total_cases_daily['Date'] = pd.to_datetime(total_cases_daily.index)
total_deaths_daily['Date'] = pd.to_datetime(total_deaths_daily.index)
Defining a function "plot_data" that takes a year as input and plots the total monthly confirmed cases and deaths for that year in radial bar. By grouping the data by month and creating radial plots, an intuitive and visually appealing way to observe COVID-19 trends over the months of a year is provided. This visualization is useful for comparing the severity of the pandemic across different times of the year.
def plot_data(year):
year_cases = total_cases_daily[total_cases_daily['Date'].dt.year == year]
year_deaths = total_deaths_daily[total_deaths_daily['Date'].dt.year == year]
# Grouping by month and summing the totals
monthly_cases = year_cases.groupby(year_cases['Date'].dt.month)['Total_Cases'].sum()
monthly_deaths = year_deaths.groupby(year_deaths['Date'].dt.month)['Total_Deaths'].sum()
months = [calendar.month_name[i] for i in monthly_cases.index] # Getting month names
N = len(months)
# Create a 2x1 subplot for cases and deaths
fig, axs = plt.subplots(1, 2, subplot_kw=dict(polar=True), figsize=(14, 7))
# Function to create a radial bar chart
def create_radial_bar(ax, values, title, color):
angles = [n / float(N) * 2 * pi for n in range(N)]
values = values.tolist() + values.tolist()[:1]
angles += angles[:1]
ax.fill(angles, values, color=color, alpha=0.25)
ax.plot(angles, values, color=color, linewidth=2)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(months)
ax.set_title(title)
# Plotting monthly confirmed cases
create_radial_bar(axs[0], monthly_cases, f'Total Monthly COVID-19 Confirmed Cases in {year}', 'blue')
# Plotting monthly deaths
create_radial_bar(axs[1], monthly_deaths, f'Total Monthly COVID-19 Deaths in {year}', 'red')
plt.tight_layout()
plt.show()
An interactive dropdown widget allowing the user to select a year for which the data visualization will be displayed. Using the interact function from the ipywidgets library to create a user interface in the Jupyter notebook.
# Interact with the user to choose the year
years = sorted(total_cases_daily['Date'].dt.year.unique())
interact(plot_data, year=Dropdown(options=years, value=years[0], description='Select Year:'))
interactive(children=(Dropdown(description='Select Year:', options=(2020, 2021, 2022, 2023), value=2020), Outp…
<function __main__.plot_data(year)>
Based on the above radar charts we can interpret that -
Initial Phase (March 2020 - October 2020): The pandemic started in March 2020, and initially, both confirmed cases and deaths were relatively normal, suggesting a gradual spread of the virus initially. This period likely represents the early spread before significant outbreaks in various regions.
Significant Spike (November 2020 - December 2020): Towards the end of 2020, there was a sharp increase in both confirmed cases and deaths. This spike can be attributed to several factors including colder weather driving people indoors where the virus spreads more easily, pandemic fatigue leading to reduced adherence to public health measures, and possibly the absence at that time of widespread vaccination programs.
Early 2021 Decrease and Mid-Year Surge (January 2021 - September 2021): The start of 2021 saw a decrease in both cases and deaths, likely due to the beginning of vaccination rollouts and improved public health strategies post-holiday season. However, there was a sudden increase again by September 2021. This resurgence could be linked to the emergence of new virus variants that were more infectious, alongside relaxed restrictions and increased public gatherings.
Consistently High Rates (2022): Throughout 2022, both confirmed cases and deaths remained high. This continued impact could reflect challenges such as vaccine distribution inequalities, variant evolution, and oscillating public health policies. The persistence of high numbers indicates that the virus remained a significant health threat, affecting substantial numbers of people across different demographics.
Declining Trend (January 2023 - March 2023): By early 2023, there was a noticeable decline in both cases and deaths. This decline could be the result of several factors, including high levels of population immunity from previous infections and vaccinations, better management of cases through improved treatment protocols, and possibly the global decline in the severity of circulating variants.
Importing necessary libraries such as pandas for data manipulation and plotly for interactive visualizations.
import pandas as pd
import plotly.graph_objs as go
from plotly.subplots import make_subplots
Loading the datasets containing COVID-19 data for confirmed cases, deaths, and vaccinations
confirmed_cases_path = 'time_series_covid19_confirmed_US.csv'
deaths_path = 'time_series_covid19_deaths_US.csv'
vaccinations_path = 'us_state_vaccinations.csv'
confirmed_cases_df = pd.read_csv(confirmed_cases_path)
deaths_df = pd.read_csv(deaths_path)
vaccinations_df = pd.read_csv(vaccinations_path)
Summing up the confirmed cases and deaths over time, and aggregating vaccination data by date.
date_columns = confirmed_cases_df.columns[11:]
confirmed_cases_sum = confirmed_cases_df[date_columns].sum()
deaths_sum = deaths_df[date_columns].sum()
vaccinations_df['date'] = pd.to_datetime(vaccinations_df['date'])
vaccinations_sum = vaccinations_df.groupby('date').sum()['people_fully_vaccinated']
Adding traces for confirmed cases, deaths, and fully vaccinated people over time.
fig = go.Figure()
fig.add_trace(go.Scatter(x=pd.to_datetime(date_columns), y=confirmed_cases_sum,
mode='lines', name='Confirmed Cases', line=dict(color='blue')))
fig.add_trace(go.Scatter(x=pd.to_datetime(date_columns), y=deaths_sum,
mode='lines', name='Deaths', line=dict(color='red')))
fig.add_trace(go.Scatter(x=vaccinations_sum.index, y=vaccinations_sum,
mode='lines', name='Fully Vaccinated', line=dict(color='green')))
fig.update_yaxes(title_text="Number of People")
fig.update_layout(title_text="COVID-19 Cases, Deaths, and Vaccinations in the U.S.",
xaxis_title='Date',
yaxis_title='Total Numbers',
height=600,
width=900,
showlegend=True)
fig.show()
As for the most important finding from this data, one crucial insight could be the relationship between the trends of COVID-19 cases, deaths, and vaccinations over time. Specifically, we can observe:
The trajectory of confirmed cases and deaths, which reflects the impact of the pandemic on public health. The effectiveness of vaccination efforts in reducing the number of fully vaccinated individuals over time. The potential correlation between vaccination rates and the decline in cases and deaths, indicating the effectiveness of vaccination campaigns in controlling the spread of the virus and mitigating its severity. This visualization allows us to track the progression of the pandemic and assess the effectiveness of intervention measures such as vaccination campaigns. It underscores the importance of widespread vaccination in combating COVID-19 and highlights the need for continued monitoring and response to emerging trends in cases and deaths.
!pip install dash
Collecting dash
Downloading dash-2.16.1-py3-none-any.whl (10.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.2/10.2 MB 583.9 kB/s eta 0:00:0000:0100:01
Requirement already satisfied: importlib-metadata in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (4.11.3)
Requirement already satisfied: requests in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (2.28.1)
Collecting retrying
Downloading retrying-1.3.4-py3-none-any.whl (11 kB)
Requirement already satisfied: setuptools in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (63.4.1)
Requirement already satisfied: typing-extensions>=4.1.1 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (4.3.0)
Collecting dash-table==5.0.0
Downloading dash_table-5.0.0-py3-none-any.whl (3.9 kB)
Requirement already satisfied: plotly>=5.0.0 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (5.9.0)
Requirement already satisfied: nest-asyncio in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (1.5.5)
Requirement already satisfied: Werkzeug<3.1 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (2.0.3)
Requirement already satisfied: Flask<3.1,>=1.0.4 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from dash) (1.1.2)
Collecting dash-html-components==2.0.0
Downloading dash_html_components-2.0.0-py3-none-any.whl (4.1 kB)
Collecting dash-core-components==2.0.0
Downloading dash_core_components-2.0.0-py3-none-any.whl (3.8 kB)
Requirement already satisfied: itsdangerous>=0.24 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from Flask<3.1,>=1.0.4->dash) (2.0.1)
Requirement already satisfied: Jinja2>=2.10.1 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from Flask<3.1,>=1.0.4->dash) (2.11.3)
Requirement already satisfied: click>=5.1 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from Flask<3.1,>=1.0.4->dash) (8.0.4)
Requirement already satisfied: tenacity>=6.2.0 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from plotly>=5.0.0->dash) (8.0.1)
Requirement already satisfied: zipp>=0.5 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from importlib-metadata->dash) (3.8.0)
Requirement already satisfied: charset-normalizer<3,>=2 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from requests->dash) (2.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from requests->dash) (2022.9.24)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from requests->dash) (1.26.11)
Requirement already satisfied: idna<4,>=2.5 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from requests->dash) (3.3)
Requirement already satisfied: six>=1.7.0 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from retrying->dash) (1.16.0)
Requirement already satisfied: MarkupSafe>=0.23 in /Users/suprajbejugam/opt/anaconda3/lib/python3.9/site-packages (from Jinja2>=2.10.1->Flask<3.1,>=1.0.4->dash) (2.0.1)
Installing collected packages: dash-table, dash-html-components, dash-core-components, retrying, dash
Successfully installed dash-2.16.1 dash-core-components-2.0.0 dash-html-components-2.0.0 dash-table-5.0.0 retrying-1.3.4